Skip to content

gh-159320: use pthread_getattr_np for stack limit checks even on musl - #159376

Open
Yhg1s wants to merge 6 commits into
python:mainfrom
Yhg1s:musl-stack-check
Open

Yhg1s wants to merge 6 commits into
python:mainfrom
Yhg1s:musl-stack-check

Conversation

@Yhg1s

@Yhg1s Yhg1s commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Adjust the use of pthread_getattr_np for stack size limit detection to avoid the problem on musl of it reporting the stack limit of the main thread incorrectly. On platforms where pthread_getattr_np underreports the main thread's stack size, use RLIMIT_STACK for the main thread instead. (Cross-compiles targeting musl will have to pass ac_cv_unreliable_pthread_getattr_np=yes to configure.)

reporting the stack limit of the main thread incorrectly. On platforms where
pthread_getattr_np underreports the main thread's stack size, use
RLIMIT_STACK for the main thread instead.
@Yhg1s

Yhg1s commented Oct 13, 2026

Copy link
Copy Markdown
Member Author

This is a more general fix than #159321, and incidentally also lets us have proper stack overflow protections on musl.

@Yhg1s

Yhg1s commented Oct 14, 2026

Copy link
Copy Markdown
Member Author

For the record, I think this should not be backported.

Comment thread Python/ceval.c Outdated
…doesn't

depend on explicitly setting the stack size. It's correct for new threads
regardless of that call.
@vstinner

Copy link
Copy Markdown
Member

Can you please make the new "HAVE" macro private? Replace the macro in configure.ac:

-     [AC_DEFINE([HAVE_UNRELIABLE_PTHREAD_GETATTR_NP], [1],
+     [AC_DEFINE([_Py_HAVE_UNRELIABLE_PTHREAD_GETATTR_NP], [1],

Something like that:

Details
diff --git a/Python/ceval.c b/Python/ceval.c
index 3ed070a5846..e0623293670 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -65,7 +65,7 @@ _Py_ReachedRecursionLimitWithMargin(PyThreadState *tstate, int margin_count)
 #  define Py_C_STACK_SIZE 4000000
 #endif
 
-#ifdef HAVE_UNRELIABLE_PTHREAD_GETATTR_NP
+#ifdef _Py_HAVE_UNRELIABLE_PTHREAD_GETATTR_NP
 #ifdef HAVE_SYS_RESOURCE_H
 #  include <sys/resource.h>
 #endif
@@ -165,7 +165,7 @@ hardware_stack_limits(uintptr_t *base, uintptr_t *top, uintptr_t sp)
         err |= pthread_attr_destroy(&attr);
     }
     if (err == 0) {
-#    ifdef HAVE_UNRELIABLE_PTHREAD_GETATTR_NP
+#    ifdef _Py_HAVE_UNRELIABLE_PTHREAD_GETATTR_NP
         /* pthread_getattr_np on the main thread of a musl process reports a
          * stack size based on the current stack rather than RLIMIT_STACK.
          * New threads are reported correctly even on musl, so this fallback
diff --git a/Tools/build/check_capi_macros_ignored.txt b/Tools/build/check_capi_macros_ignored.txt
index cfa37c2b137..238c29b7039 100644
--- a/Tools/build/check_capi_macros_ignored.txt
+++ b/Tools/build/check_capi_macros_ignored.txt
@@ -627,7 +627,6 @@ HAVE_UNAME
 HAVE_UNISTD_H
 HAVE_UNLINKAT
 HAVE_UNLOCKPT
-HAVE_UNRELIABLE_PTHREAD_GETATTR_NP
 HAVE_UNSHARE
 HAVE_USABLE_WCHAR_T
 HAVE_UTIL_H
diff --git a/configure b/configure
index 221907add48..744ee2beef4 100755
--- a/configure
+++ b/configure
@@ -21875,7 +21875,7 @@ printf "%s\n" "$ac_cv_unreliable_pthread_getattr_np" >&6; }
    if test "x$ac_cv_unreliable_pthread_getattr_np" = xyes
 then :
 
-printf "%s\n" "#define HAVE_UNRELIABLE_PTHREAD_GETATTR_NP 1" >>confdefs.h
+printf "%s\n" "#define _Py_HAVE_UNRELIABLE_PTHREAD_GETATTR_NP 1" >>confdefs.h
 
 fi
 fi
diff --git a/configure.ac b/configure.ac
index e523314b492..42844ab64ca 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5620,7 +5620,7 @@ int main(void) {
       [ac_cv_unreliable_pthread_getattr_np=yes],
       [ac_cv_unreliable_pthread_getattr_np=no])])
    AS_VAR_IF([ac_cv_unreliable_pthread_getattr_np], [yes],
-     [AC_DEFINE([HAVE_UNRELIABLE_PTHREAD_GETATTR_NP], [1],
+     [AC_DEFINE([_Py_HAVE_UNRELIABLE_PTHREAD_GETATTR_NP], [1],
        [Define if pthread_getattr_np under-reports the main thread's stack size (musl behaviour).])])])
 
 # os.statx uses Linux's statx function.  AIX also has a function named statx,
diff --git a/pyconfig.h.in b/pyconfig.h.in
index 4193d536f3b..1fdeb7d9f2f 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -1706,10 +1706,6 @@
 /* Define to 1 if you have the 'unlockpt' function. */
 #undef HAVE_UNLOCKPT
 
-/* Define if pthread_getattr_np under-reports the main thread's stack size
-   (musl behaviour). */
-#undef HAVE_UNRELIABLE_PTHREAD_GETATTR_NP
-
 /* Define to 1 if you have the 'unshare' function. */
 #undef HAVE_UNSHARE
 
@@ -2227,6 +2223,10 @@
 /* Define if you have the 'tanpi' function. */
 #undef _Py_HAVE_TANPI
 
+/* Define if pthread_getattr_np under-reports the main thread's stack size
+   (musl behaviour). */
+#undef _Py_HAVE_UNRELIABLE_PTHREAD_GETATTR_NP
+
 /* Thread stack size set by the linker (in bytes). */
 #undef _Py_LINKER_THREAD_STACK_SIZE
 

@vstinner

Copy link
Copy Markdown
Member

See also #159604 for FreeBSD.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants